package com.ruoyi.pos.api.service.task.impl;

import com.ruoyi.common.enums.*;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.common.utils.shandianbao.*;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.pos.api.service.task.IShandianbaoService;
import com.ruoyi.pos.api.utils.CommonUtils;
import com.ruoyi.pos.web.domain.*;
import com.ruoyi.pos.web.mapper.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * @author luobo
 * @title: SandianbaoServiceImpl
 * @projectName pos
 * @description: 处理三点包相关业务逻辑
 * @date 2022-04-08 14:13:26
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class ShandianbaoServiceImpl implements IShandianbaoService {
    private final ShandianbaoUtils shandianbaoUtils;
    private final ShandianbaoConfig shandianbaoConfig;
    private final TUserInfoMapper userInfoMapper;
    private final TTerminalInfoMapper terminalInfoMapper;
    private final TTerminalBrandInfoMapper terminalBrandInfoMapper;
    private final TTerminalTransFlowInfoMapper terminalTransFlowInfoMapper;
    private final TStatisticInfoMapper statisticInfoMapper;
    private final CommonUtils commonUtils;


    @Override
    public TTerminalBrandInfo queryTTerminalBrandInfo() {
        TTerminalBrandInfo mapper = new TTerminalBrandInfo();
        mapper.setBrand("闪电宝");
        mapper.setIsValid("0");
        List<TTerminalBrandInfo> brandList = terminalBrandInfoMapper.selectTTerminalBrandInfoList(mapper);
        if (null != brandList && brandList.size() > 0) {
            return brandList.get(0);
        }
        return null;
    }

    @Override
    public List<TUserInfo> queryUserList() {
        TUserInfo mapper = new TUserInfo();
        mapper.setShandianAuthFlag(ShandianFlagEnum.WAIT_SNGY.getCode());
        List<TUserInfo> userList = userInfoMapper.selectTUserInfoList(mapper);
        return userList;
    }

    @Override
    @Transactional
    public void syncRegInfo(TUserInfo user, TTerminalBrandInfo brand) throws Exception {
        Calendar c = Calendar.getInstance();
        c.setTime(brand.getSynTime());
        c.add(Calendar.SECOND, 300); //5分钟轮询一次
        ApiRequestBean request = ApiRequestBean.builder()
                .rugrId(shandianbaoConfig.getRugrId())
                .beginTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, brand.getSynTime()))
                .endTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, c.getTime()))
                .phoneNo(user.getUserPhone())
                .build(); //注册信息查询
        log.info("获取商户号请求接口参数：{}", request);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(user.getShandianAuthTime());
        calendar.add(Calendar.HOUR, 24);
        if (calendar.getTime().before(new Date())) { //说明已经超过24小时，则更新状态，不再进行下一次的轮训
            user.setShandianAuthFlag(ShandianFlagEnum.WAIT_REG.getCode());
            user.setUpdateTime(new Date());
            userInfoMapper.updateTUserInfo(user);
        }

        List<ApiResultRegBean> regList = shandianbaoUtils.queryRegInfoList(request);
        Optional.ofNullable(regList).ifPresent(list ->{
            ApiResultRegBean bean = list.get(0);
            if (user.getUserPhone().equals(bean.getPhoneNo())) { //比对手机号
                //插入一条终端记录
                TTerminalInfo terminalInfo = new TTerminalInfo();
                terminalInfo.setSnCode(bean.getSaruLruid());
                terminalInfo.setId(IdUtils.simpleUUID());
                terminalInfo.setAddTime(new Date());
                terminalInfo.setUserId(user.getUserId());
                terminalInfo.setUserName(user.getUserName());
                terminalInfo.setPhone(user.getUserPhone());
                terminalInfo.setBrandId(brand.getId());
                terminalInfo.setTerminalType(TerminalTypeEnum.BUY.getCode());
                terminalInfo.setTransStatus(TransStatusEnum.HAS_CONFIIRM.getCode());
                terminalInfo.setActivateStatus(YesOrNoEnums.NO.getCode());
                terminalInfo.setActivateTime(DateUtils.getNowDate());
                terminalInfo.setBindingStatus(YesOrNoEnums.NO.getCode());
                terminalInfo.setBindingTime(DateUtils.getNowDate());
                terminalInfo.setTerminalGmv(BigDecimal.ZERO);
                terminalInfo.setTerminalNum(BigDecimal.ZERO);
                terminalInfo.setTransStatus(TransStatusEnum.HAS_CONFIIRM.getCode());
                //默认绑定
                terminalInfoMapper.insertTTerminalInfo(terminalInfo);

                //插入一条统计记录
                TStatisticInfo statistic = statisticInfoMapper.selectTStatisticInfoForCurrentDay(user.getUserId(), brand.getId());
                if (null == statistic) {
                    statistic = commonUtils.generateStatisticInfo(user, DateUtils.getNowDate(), brand.getId());
                    statisticInfoMapper.insertTStatisticInfo(statistic);
                }
                statistic.setMyTerminalNum(statistic.getMyTerminalNum().subtract(BigDecimal.ONE));
                statisticInfoMapper.updateTStatisticInfo(statistic);

                //更新用户闪电宝数据同步状态为已同步
                user.setShandianAuthFlag(ShandianFlagEnum.HAS_SNGY.getCode());
                user.setUpdateTime(new Date());
                userInfoMapper.updateTUserInfo(user);
            } else {
                log.info("无效的手机号：{}，数据不落地", bean.getPhoneNo());
            }
        });
    }

    @Override
    @Transactional
    public void syncAuthInfo(TUserInfo user, TTerminalBrandInfo brand) throws Exception {
        Calendar c = Calendar.getInstance();
        c.setTime(brand.getSynTime());
        c.add(Calendar.SECOND, 300); //5分钟轮询一次
        ApiRequestBean request = ApiRequestBean.builder()
                .rugrId(shandianbaoConfig.getRugrId())
                .beginTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, brand.getSynTime()))
                .endTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, c.getTime()))
                .phoneNo(user.getUserPhone())
                .build(); //注册信息查询
        log.info("获取注册信息请求接口参数：{}", request);
        List<ApiResultAuthBean> regList = shandianbaoUtils.queryAuthInfoList(request);
        Optional.ofNullable(regList).ifPresent(list ->{
            ApiResultAuthBean bean = list.get(0);
            TTerminalInfo terminal = terminalInfoMapper.selectTTerminalInfoBySnCode(bean.getSaruLruid());
            if (null != terminal) {
                terminal.setUserName(bean.getShandianName());
                BeanUtils.copyProperties(bean, user);
                userInfoMapper.updateTUserInfo(user);
            } else {
                log.info("无效的商户号：{}", bean.getSaruLruid());
            }
        });
    }

    @Override
    @Transactional
    public void syncTransInfo(TTerminalBrandInfo brand) throws Exception {
        Calendar c = Calendar.getInstance();
        c.setTime(brand.getSynTime());
        c.add(Calendar.SECOND, 300); //5分钟轮询一次
        ApiRequestBean request = ApiRequestBean.builder()
                .rugrId(shandianbaoConfig.getRugrId())
                .beginTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, brand.getSynTime()))
                .endTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, c.getTime()))
                .build(); //交易信息查询
        brand.setSynTime(c.getTime());
        if (brand.getSynTime().after(new Date())) { //说明定时任务循环太快，超过了当前系统时间，下次执行的时候以当前时间往前回退5分钟，防止数据遗漏
            c = Calendar.getInstance();
            c.setTime(new Date());
            c.add(Calendar.SECOND, -300); //往前回退5分钟
            brand.setSynTime(c.getTime());
        }
        terminalBrandInfoMapper.updateTTerminalBrandInfo(brand); //更新下次查询的开始时间
        List<ApiResultTransBean> transList = shandianbaoUtils.queryTransInfoList(request);
        Optional.ofNullable(transList).ifPresent(list ->{
            list.stream().forEach(bean ->{
                if (bean.getTransTime().before(brand.getSynTime())) { //说明这笔交易是在平台对接之前的交易，直接舍弃
                    log.info("历史交易记录，不做处理，订单号：" + bean.getOrderId() + "，第三方交易时间：" + bean.getTransTime());
                    return;
                }
                TTerminalTransFlowInfo mapper = new TTerminalTransFlowInfo();
                mapper.setOrderId(bean.getOrderId());
                List<TTerminalTransFlowInfo> flowList = terminalTransFlowInfoMapper.selectTTerminalTransFlowInfoList(mapper); //查询该订单是否已经接收过
                if (null != flowList && flowList.size() > 0) {
                    log.info("该订单已接收，订单号：" + bean.getOrderId());
                    return;
                } else { //数据落地
                    TTerminalTransFlowInfo flow = new TTerminalTransFlowInfo();
                    BeanUtils.copyProperties(bean, flow);
                    flow.setTransAmount(flow.getTransAmount().multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_FLOOR)); //金额乘100，,转换为分，便于后续定时任务统一处理
                    flow.setCardType("1");
                    flow.setId(IdUtils.simpleUUID());
                    flow.setCreateTime(DateUtils.getNowDate());
                    flow.setIsValid(YesOrNoEnums.YES.getCode());
                    flow.setHandleStaus(HandleStausEnum.NO_HANDLE.getCode());
                    if ("O110909".equals(bean.getCpiNo()) || "O111515".equals(bean.getCpiNo())) { //说明是pos机交易
                        if ("VIPPAY".equals(bean.getBcconMark())) { //说明是pos机激活交易，本地不处理这种数据，所以默认为处理成功
                            flow.setHandleStaus(HandleStausEnum.HAS_HANDLE.getCode());
                            flow.setHandleResult("闪电宝激活交易：VIPPAY");
                            flow.setPayType(PayTypeEnum.SHANDIAN_ACTIVATY.getCode());
                        } else if ("CARDPAY".equals(bean.getBcconMark()) || "QUICKPAY".equals(bean.getBcconMark())){ //pos机刷卡
                            if ("O110909".equals(bean.getCpiNo())){
                                flow.setPayType(PayTypeEnum.SHANDIAN_1_09_1.getCode());
                                flow.setCardType("1");
                            } else {
                                flow.setPayType(PayTypeEnum.SHANDIAN_1_15_1.getCode());
                                flow.setCardType("1");
                            }
                        } else { //pos机扫码
                            if ("O111515".equals(bean.getCpiNo())){
                                flow.setPayType(PayTypeEnum.SHANDIAN_2_09_2.getCode());
                            } else {
                                flow.setPayType(PayTypeEnum.SHANDIAN_2_15_2.getCode());
                            }
                        }
                    } else { //说明是商户号交易，默认将商户号当做终端号，全部都按照扫码来计算
                        flow.setSnCode(bean.getSaruLruid());
                        flow.setPayType(bean.getCpiNo());
                    }
                    terminalTransFlowInfoMapper.insertTTerminalTransFlowInfo(flow);
                }
            });
        });
    }
}
